package com.ins1st.plus.core.handler;

import com.ins1st.plus.api.system.log.entity.SysLog;
import com.ins1st.plus.api.system.log.service.SysLogApi;
import com.ins1st.plus.core.annotation.Req4Json;
import com.ins1st.plus.util.RequestUtil;
import com.ins1st.plus.util.SpringBeanFactoryUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Calendar;

/**
 * @program: ins1st-plus
 * @description: 日志拦截器
 * @author: coderSun
 * @create: 2019-09-09 17:41
 **/
@Component
public class LogInterceptorAdapter extends HandlerInterceptorAdapter {

    private static final Logger log = LoggerFactory.getLogger(LogInterceptorAdapter.class);

    private static final ThreadLocal<Long> THREAD_LOCAL = new ThreadLocal<>();


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        THREAD_LOCAL.set(Calendar.getInstance().getTimeInMillis());
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if ((handler instanceof HandlerMethod)) {
            HandlerMethod method = (HandlerMethod) handler;
            boolean hasLoginAnnotation = method.getMethod().isAnnotationPresent(Req4Json.class);
            if (hasLoginAnnotation) {
                SysLog sysLog = new SysLog();
                Req4Json req4Json = method.getMethod().getAnnotation(Req4Json.class);
                StringBuffer rq = new StringBuffer("[");
                if (StringUtils.isNotBlank(req4Json.parameters())) {
                    String[] params = req4Json.parameters().split(",");
                    for (String str : params) {
                        rq.append(str + ":" + request.getParameter(str));
                    }
                }
                rq.append("]");
                sysLog.setLogTitle(req4Json.log());
                sysLog.setRequestIp(RequestUtil.getIpAddr(request));
                sysLog.setRequestMethod(method.getMethod().getName());
                sysLog.setRequestParams(rq.toString());
                sysLog.setRequestClass(method.getBeanType().toString());
                sysLog.setRequestUrl(request.getRequestURL().toString());
                if (ex == null) {
                    sysLog.setRequestSuccess("成功");
                } else {
                    sysLog.setRequestSuccess("失败");
                    sysLog.setExMessage(ex.getMessage());
                }
                Long m = (Calendar.getInstance().getTimeInMillis() - THREAD_LOCAL.get()) / 1000;
                sysLog.setRequestTime(String.valueOf(m));
                log.info("\n--->请求IP：{}\n--->请求地址：{}\n---> 类名：{}\n---> 方法名：{}\n---> 标题：{}\n---> 参数：{}\n---> 是否保存数据库：{}"
                        , RequestUtil.getIpAddr(request)
                        , request.getRequestURL()
                        , method.getBeanType()
                        , method.getMethod().getName()
                        , req4Json.log()
                        , rq.toString()
                        , req4Json.db() ? "是" : "否");
                SysLogApi sysLogApi = SpringBeanFactoryUtils.getBean("sysLogApi", SysLogApi.class);
                sysLogApi.save(sysLog);
            }
        }
        super.afterCompletion(request, response, handler, ex);
    }
}
